﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System.IO;

namespace Genuilder.Extensibility.Targets
{
	class MSBuildPlugin : IPlugin
	{

		ITaskItem[] _Sources;
		public MSBuildPlugin(ITaskItem[] sources)
		{
			_Sources = sources;
			OutputPath = "";
		}

		public String OutputPath
		{
			get;
			set;
		}

		#region IPlugin Members

		public void Initialize(ICodeRepository repository)
		{
			repository.CodeItemCreated += new CodeItemCreatedHandler(repository_CodeTracked);
		}

		void repository_CodeTracked(ICodeRepository sender, CodeItem item)
		{
			_TrackedItems.Add(item);
			item.StateChanged += new StateChangedHandler(item_StateChanged);
		}

		void item_StateChanged(CodeItem sender, CodeItemState newState, CodeItemState oldState)
		{
			if(newState == CodeItemState.Excluded)
				_ExcludedItems.Add(sender);
			if(newState == CodeItemState.Deleted)
				_DeletedItems.Add(sender);
		}


		public ITaskItem[] OutputSources
		{
			get
			{
				var generatedFiles = TrackedItems
					.OfType<FileCodeItem>()
					.Where(i => i.State == CodeItemState.Exist && !_Sources.Any(ti => new FileInfo(ti.ItemSpec).FullName == i.File.FullName))
					.Select(i => new TaskItem(i.File.FullName));
				var deletedOrExcluded = DeletedOrExcludedItems
					.OfType<FileCodeItem>()
					.ToDictionary((i) => i.File.FullName);
				return _Sources
					.Where(i => !deletedOrExcluded.ContainsKey(new FileInfo(i.ItemSpec).FullName))
					.Where(i => File.Exists(i.ItemSpec))
					.Concat(generatedFiles.OfType<ITaskItem>())
					.ToArray();
			}
		}

		private readonly List<CodeItem> _TrackedItems = new List<CodeItem>();
		public IEnumerable<CodeItem> TrackedItems
		{
			get
			{
				return _TrackedItems;
			}
		}

		public IEnumerable<CodeItem> DeletedOrExcludedItems
		{
			get
			{
				return _DeletedItems.Concat(_ExcludedItems);
			}
		}

		private readonly List<CodeItem> _DeletedItems = new List<CodeItem>();
		public IEnumerable<CodeItem> DeletedItems
		{
			get
			{
				return _DeletedItems;
			}
		}

		private readonly List<CodeItem> _ExcludedItems = new List<CodeItem>();
		public IEnumerable<CodeItem> ExcludedItems
		{
			get
			{
				return _ExcludedItems;
			}
		}
		#endregion
	}
}
